package com.next

import groovy.transform.CompileStatic
import groovy.transform.TypeChecked

@CompileStatic
@TypeChecked
class AppOpportunityService
{
    static scope = "singleton"

    /**
     * @Author 班旭娟* @ModifiedDate 2017-4-21
     */
    def initOpportunity(Opportunity opportunity, Workflow workflow = null)
    {
        println "in"
        def territoryAccount = TerritoryAccount.find("from TerritoryAccount where account.id = ?", [opportunity?.account?.id])
        def territory = territoryAccount?.territory
        def flag = true

        opportunity.territory = territory
        opportunity.save flush: true

        initTeam(opportunity, workflow)

        initFlexFieldCategory(opportunity, workflow)

        def workflowInstance = new WorkflowInstance(opportunity: opportunity)
        if (!workflow)
        {
            def territoryWorkflowList = TerritoryWorkflow.findAll("from TerritoryWorkflow where territory.id = ${territory?.id}")
            territoryWorkflowList?.each {
                if (it?.workflow?.active)
                {
                    workflowInstance.workflow = it?.workflow
                    workflowInstance.name = opportunity?.serialNumber + "-" + it?.workflow?.name
                }
            }
        }
        else
        {
            workflowInstance.workflow = workflow
            workflowInstance.name = opportunity?.serialNumber + "-" + workflow?.name
        }

        println "sssssss"
        workflowInstance.save flush: true
        initWorkflowInstance(workflowInstance)

    }

    def initWorkflowInstance(WorkflowInstance workflowInstance)
    {

        initWorkflowInstanceStage(workflowInstance)

        def workflowInstanceStage = WorkflowInstanceStage.find("from WorkflowInstanceStage where instance.id = ${workflowInstance?.id} order by executionSequence asc")
        def workflowInstanceStatus = WorkflowInstanceStatus.find("from WorkflowInstanceStatus order by id asc")
        workflowInstance.stage = workflowInstanceStage
        workflowInstance.status = workflowInstanceStatus
        workflowInstance.save flush: true
    }

    def initWorkflowInstanceStage(WorkflowInstance workflowInstance)
    {

        def workflow = workflowInstance?.workflow
        def opportunity = workflowInstance?.opportunity
        def workflowInstanceStage

        def workflowStages = WorkflowStage.findAll("from WorkflowStage where workflow.id = ${workflow?.id} order by executionSequence asc")
        workflowStages?.each {
            workflowInstanceStage = WorkflowInstanceStage.find("from WorkflowInstanceStage where instance.id = ? and name = ?", [workflowInstance?.id, it?.name])
            if (!workflowInstanceStage)
            {
                workflowInstanceStage = new WorkflowInstanceStage()
                workflowInstanceStage.instance = workflowInstance
                workflowInstanceStage.executionSequence = it?.executionSequence
                workflowInstanceStage.name = it?.name
                workflowInstanceStage.canReject = it?.canReject
                workflowInstanceStage.desktopLayout = it?.desktopLayout
                workflowInstanceStage.save flush: true

                initWorkflowInstanceUser(workflowInstanceStage, opportunity, it)
                initWorkflowInstanceNotification(workflowInstanceStage, opportunity, it)
                initWorkflowInstanceEvent(workflowInstanceStage, it)
            }
        }
        initWorkflowInstanceCondition(workflowInstance)
    }

    def initWorkflowInstanceUser(WorkflowInstanceStage workflowInstanceStage, Opportunity opportunity, WorkflowStage workflowStage)
    {
        def workflowInstanceUser

        def workflowUsers = WorkflowUser.findAll("from WorkflowUser where stage.id = ${workflowStage?.id}")
        def opportunityTeams = OpportunityTeam.findAll("from OpportunityTeam where opportunity.id = ${opportunity?.id}")
        workflowUsers?.each { workflowUser ->
            opportunityTeams?.each { opportunityTeam ->
                if (opportunityTeam?.user?.position == workflowUser?.position)
                {
                    workflowInstanceUser = WorkflowInstanceUser.find("from WorkflowInstanceUser where user.id = ${opportunityTeam?.user?.id} and stage.id = ${workflowInstanceStage?.id}")
                    if (!workflowInstanceUser)
                    {
                        workflowInstanceUser = new WorkflowInstanceUser()
                        workflowInstanceUser.stage = workflowInstanceStage
                        workflowInstanceUser.user = opportunityTeam?.user
                        workflowInstanceUser.authority = workflowUser?.authority
                        workflowInstanceUser.save flush: true
                    }
                }
            }
        }
    }

    def initWorkflowInstanceNotification(WorkflowInstanceStage workflowInstanceStage, Opportunity opportunity, WorkflowStage workflowStage)
    {
        def workflowInstanceNotification

        def workflowNotifications = WorkflowNotification.findAll("from WorkflowNotification where stage.id = ${workflowStage?.id}")
        def opportunityTeams = OpportunityTeam.findAll("from OpportunityTeam where opportunity.id = ${opportunity?.id}")
        workflowNotifications?.each { workflowNotification ->
            if (workflowNotification?.position)
            {
                opportunityTeams?.each { opportunityTeam ->
                    if (opportunityTeam?.user?.position == workflowNotification?.position)
                    {
                        workflowInstanceNotification = WorkflowInstanceNotification.find("from WorkflowInstanceNotification where user.id = ? and stage.id = ? and messageTemplate.id = ? and cellphone = ?", [opportunityTeam?.user?.id, workflowInstanceStage?.id, workflowNotification?.messageTemplate?.id, workflowNotification?.cellphone])
                        if (!workflowInstanceNotification)
                        {
                            workflowInstanceNotification = new WorkflowInstanceNotification()
                            workflowInstanceNotification.stage = workflowInstanceStage
                            workflowInstanceNotification.user = opportunityTeam?.user
                            workflowInstanceNotification.messageTemplate = workflowNotification?.messageTemplate
                            workflowInstanceNotification.toManager = workflowNotification?.toManager
                            workflowInstanceNotification.cellphone = workflowNotification?.cellphone
                            workflowInstanceNotification.save flush: true
                        }
                    }
                }
            }
            else
            {
                workflowInstanceNotification = WorkflowInstanceNotification.find("from WorkflowInstanceNotification where user.id is null and stage.id = ? and messageTemplate.id = ? and cellphone = ?", [workflowNotification?.messageTemplate?.id, workflowNotification?.messageTemplate?.id, workflowNotification?.cellphone])
                if (!workflowInstanceNotification)
                {
                    workflowInstanceNotification = new WorkflowInstanceNotification()
                    workflowInstanceNotification.stage = workflowInstanceStage
                    workflowInstanceNotification.messageTemplate = workflowNotification?.messageTemplate
                    workflowInstanceNotification.toManager = workflowNotification?.toManager
                    workflowInstanceNotification.cellphone = workflowNotification?.cellphone
                    workflowInstanceNotification.save flush: true
                }
            }
        }
    }

    def initWorkflowInstanceEvent(WorkflowInstanceStage workflowInstanceStage, WorkflowStage workflowStage)
    {
        def workflowInstanceEvent

        def workflowEvents = WorkflowEvent.findAll("from WorkflowEvent where stage.id = ${workflowStage?.id} order by executeSequence asc")
        workflowEvents?.each {
            workflowInstanceEvent = WorkflowInstanceEvent.find("from WorkflowInstanceEvent where stage.id = ${workflowInstanceStage?.id} and component.id = ${it?.component?.id}")
            if (!workflowInstanceEvent)
            {
                workflowInstanceEvent = new WorkflowInstanceEvent()
                workflowInstanceEvent.stage = workflowInstanceStage
                workflowInstanceEvent.isSynchronous = it?.isSynchronous
                workflowInstanceEvent.executeSequence = it?.executeSequence
                workflowInstanceEvent.logs = it?.logs
                workflowInstanceEvent.component = it?.component
                workflowInstanceEvent.save flush: true
            }
        }
    }

    def initWorkflowInstanceCondition(WorkflowInstance workflowInstance)
    {
        def workflow = workflowInstance?.workflow
        def workflowStages = WorkflowStage.findAll("from WorkflowStage where workflow.id = ${workflow?.id} order by executionSequence asc")
        def workflowInstanceStage
        def workflowConditions
        def workflowInstanceNextStage
        def workflowInstanceCondition

        workflowStages?.each { workflowStage ->
            workflowInstanceStage = WorkflowInstanceStage.find("from WorkflowInstanceStage where instance.id = ? and name = ?", [workflowInstance?.id, workflowStage?.name])
            workflowConditions = WorkflowCondition.findAll("from WorkflowCondition where stage.id = ${workflowStage?.id} order by executeSequence asc")
            workflowConditions?.each {
                workflowInstanceNextStage = WorkflowInstanceStage.find("from WorkflowInstanceStage where instance.id = ? and name = ?", [workflowInstance?.id, it?.nextStage?.name])
                workflowInstanceCondition = WorkflowInstanceCondition.find("from WorkflowInstanceCondition where stage.id = ${workflowInstanceStage?.id} and component.id =  ${it?.component?.id} and nextStage.id = ${workflowInstanceNextStage?.id}")
                if (!workflowInstanceCondition)
                {
                    workflowInstanceCondition = new WorkflowInstanceCondition()
                    workflowInstanceCondition.stage = workflowInstanceStage
                    workflowInstanceCondition.executeSequence = it?.executeSequence
                    workflowInstanceCondition.message = it?.message
                    workflowInstanceCondition.logs = it?.logs
                    workflowInstanceCondition.component = it?.component
                    workflowInstanceCondition.nextStage = workflowInstanceNextStage
                    workflowInstanceCondition.save flush: true
                }
            }
        }
    }

    Boolean initTeam(Opportunity opportunity, Workflow workflow = null)
    {
        Boolean inheritTeam = true
        OpportunityTeam opportunityTeam
        def territoryTeams
        def territoryAccount
        def territory

        //区域
        if (workflow)
        {
            territory = TerritoryWorkflow.find("from TerritoryWorkflow where workflow.id = ?", [workflow?.id])?.territory
        }
        else
        {
            territoryAccount = TerritoryAccount.find("from TerritoryAccount where account.id = ?", [opportunity?.account?.id])
            territory = territoryAccount?.territory
        }
        //添加owner到team
        opportunityTeam = OpportunityTeam.find("from OpportunityTeam where user.id = ? and opportunity.id = ?",
                                               [opportunity?.user?.id, opportunity?.id])
        if (!opportunityTeam)
        {
            opportunityTeam = new OpportunityTeam()
            opportunityTeam.user = opportunity?.user
            opportunityTeam.opportunity = opportunity
            if (opportunityTeam.validate())
            {
                opportunityTeam.save flush: true
            }
            else
            {
                opportunityTeam.errors.each {
                    println "${it}"
                }
            }
        }

        //复制territoryTeam到team
        while (territory)
        {
            //依次继承所有父级区域team
            if (inheritTeam)
            {
                territoryTeams = TerritoryTeam.findAll("from TerritoryTeam where territory.id = ?", [territory?.id])
                for (
                    team in
                        territoryTeams)
                {
                    opportunityTeam = OpportunityTeam.find("from OpportunityTeam where opportunity.id = ? and user" + ".id=?", [opportunity?.id, team?.user?.id])
                    if (!opportunityTeam)
                    {
                        opportunityTeam = new OpportunityTeam()
                        opportunityTeam.user = team?.user
                        opportunityTeam.opportunityLayout = team?.opportunityLayout
                        opportunityTeam.opportunity = opportunity
                        if (opportunityTeam.validate())
                        {
                            opportunityTeam.save flush: true
                        }
                        else
                        {
                            opportunityTeam.errors.each {
                                println "${it}"
                            }
                        }
                    }
                }

                inheritTeam = territory?.inheritTeam
                territory = territory?.parent
            }
            else
            {
                break
            }
        }
    }

    Boolean initFlexFieldCategory(Opportunity opportunity, Workflow workflow = null)
    {
        println "initFlexFieldCategory"
        //        Boolean inheritTeam = true
        OpportunityFlexFieldCategory opportunityFlexFieldCategory
        OpportunityFlexField opportunityFlexField
        OpportunityFlexFieldValue opportunityFlexFieldValue
        def territoryFlexFieldCategories
        SortedSet<FlexField> fields
        SortedSet<FlexFieldValue> values
        def territoryAccount
        def territory

        //区域
        if (workflow)
        {
            territory = TerritoryWorkflow.find("from TerritoryWorkflow where workflow.id = ?", [workflow?.id])?.territory
        }
        else
        {
            territoryAccount = TerritoryAccount.find("from TerritoryAccount where account.id = ?", [opportunity?.account?.id])
            territory = territoryAccount?.territory
        }

        //复制territoryFlexFieldCategory到opportunityFlexFieldCategory
        while (territory)
        {
            territoryFlexFieldCategories = TerritoryFlexFieldCategory.findAll("from TerritoryFlexFieldCategory where territory.id = ? and opportunityType.id = ?", [territory?.id, opportunity?.type?.id])
            if (territoryFlexFieldCategories)
            {
                for (
                    flexFieldCategories in
                        territoryFlexFieldCategories)
                {
                    opportunityFlexFieldCategory = OpportunityFlexFieldCategory.find("from OpportunityFlexFieldCategory where opportunity.id = ? and flexFieldCategory" + ".id=?", [opportunity?.id, flexFieldCategories?.flexFieldCategory?.id])
                    if (!opportunityFlexFieldCategory)
                    {
                        opportunityFlexFieldCategory = new OpportunityFlexFieldCategory()
                        opportunityFlexFieldCategory.flexFieldCategory = flexFieldCategories?.flexFieldCategory
                        opportunityFlexFieldCategory.opportunity = opportunity
                        if (opportunityFlexFieldCategory.validate())
                        {
                            opportunityFlexFieldCategory.save flush: true
                        }
                        else
                        {
                            println opportunityFlexFieldCategory.errors
                        }
                        fields = flexFieldCategories?.flexFieldCategory?.fields
                        if (fields)
                        {
                            for (
                                FlexField field in
                                    fields)
                            {
                                opportunityFlexField = new OpportunityFlexField()
                                opportunityFlexField.category = opportunityFlexFieldCategory
                                opportunityFlexField.dataType = field?.dataType
                                opportunityFlexField.defaultValue = field?.defaultValue
                                opportunityFlexField.description = field?.description
                                opportunityFlexField.name = field?.name
                                opportunityFlexField.displayOrder = field?.displayOrder
                                opportunityFlexField.displayType = field?.displayType
                                opportunityFlexField.valueConstraints = field?.valueConstraints
                                if (opportunityFlexField.validate())
                                {
                                    opportunityFlexField.save flush: true
                                }
                                else
                                {
                                    println opportunityFlexField.errors
                                }
                                values = field?.values
                                if (values)
                                {
                                    for (
                                        def value in
                                            values)
                                    {
                                        opportunityFlexFieldValue = new OpportunityFlexFieldValue()
                                        opportunityFlexFieldValue.field = opportunityFlexField
                                        opportunityFlexFieldValue.value = value?.value
                                        opportunityFlexFieldValue.displayOrder = value?.displayOrder
                                        if (opportunityFlexFieldValue.validate())
                                        {
                                            opportunityFlexFieldValue.save flush: true
                                        }
                                        else
                                        {
                                            println opportunityFlexFieldValue.errors
                                        }
                                    }

                                }
                            }
                        }
                    }
                }
            }
            territory = territory?.parent
        }
    }
}
